# -*- coding: utf-8 -*-
from qiniu import Auth
from qiniu import BucketManager
import os, time
import threading
import requests, json

finish = []
parts = []


def qiniu_delete_res(file):
    access_key = "EjQy0QGvHw7DWKwL5ZD9DrhcZWWkXv7P9eYZ8VKz"
    secret_key = "NoFBsyVXMtH1Eq63F5O9jg1KjjqlZ1nT7xfKSJXb"
    # 初始化Auth状态
    q = Auth(access_key, secret_key)
    # 初始化BucketManager
    bucket = BucketManager(q)
    # 你要测试的空间， 并且这个key在你空间中存在
    bucket_name = "3vppt"
    key = file
    # 删除bucket_name 中的文件 key
    ret, info = bucket.delete(bucket_name, key)
    print(info)
    assert ret == {}


class qiMainThead:
    def __init__(self):
        self.token = self.hasToken()  # print(f"获取七牛云上传token:{self.token}")
        self.mid = self.hasUploadId(
            self.token
        )  # print(f"获取七牛云上传分块:{self.mid}")

    def doUpload(self, ani):
        # 分件分块
        parts.clear()
        finish.clear()
        idx, threads, chunk_size = 1, [], 1024 * 1024 * 5
        with open(ani, "rb") as fs:
            while True:
                chunk = fs.read(chunk_size)  # 读取分块
                if not chunk:
                    break
                threads.append(partThread(self.token, self.mid["uploadId"], idx, chunk))
                idx += 1
        # 启动任务
        for t in threads:
            t.start()
        for t in threads:
            t.join()
        # 合并文件
        if len(finish):
            print(f"分片上传失败:{finish}")
            return None
        u = self.finishedUpload(self.token, self.mid["uploadId"], ani)
        print(f"七牛云合并分块{u}")
        # r = self.web.finishMysqlDB(u["key"], ani[1], ani[2])
        # print(f"当前任务完成: {r}")
        # 移除文件
        os.remove(ani)
        return u

    def hasUploadId(self, token):
        """请求分块任务ID"""
        url = "http://up-cn-east-2.qiniup.com/buckets/3vppt/objects/~/uploads"
        headers = {
            "Host": "up-cn-east-2.qiniup.com",
            "Authorization": f"UpToken {token}",
        }
        try:
            res = requests.post(url, headers=headers, verify=False)
            return res.json() if res and res.status_code == 200 else None
        except BaseException as err:
            return None

    def hasToken(self):
        """请求上传token"""
        access_key = "EjQy0QGvHw7DWKwL5ZD9DrhcZWWkXv7P9eYZ8VKz"
        secret_key = "NoFBsyVXMtH1Eq63F5O9jg1KjjqlZ1nT7xfKSJXb"
        q = Auth(access_key, secret_key)
        # 要上传的空间
        bucket_name = "3vppt"
        # 上传后保存的文件名
        key = None
        policy = {
            "forceSaveKey": True,
            "saveKey": "ppt_media/$(etag)&$(fname)",
            "returnUrl": None,
            "returnBody": json.dumps(
                {"key": "$(key)", "hash": "$(etag)", "fname": "$(fname)"}
            ),
        }
        token = q.upload_token(bucket_name, key, 3600, policy)
        return token

    def finishedUpload(self, token, uid, file):
        """分块上传完成"""
        url = f"http://up-cn-east-2.qiniup.com/buckets/3vppt/objects/~/uploads/{uid}"
        headers = {
            "Host": "up-cn-east-2.qiniup.com",
            "Content-Type": "application/json",
            "Authorization": f"UpToken {token}",
        }
        sorted_x = sorted(parts, key=lambda x: x["partNumber"])
        data = {"parts": sorted_x, "fname": file.split("/")[-1]}
        try:
            res = requests.post(
                url, headers=headers, data=json.dumps(data), verify=False
            )
            return res.json() if res and res.status_code == 200 else None
        except BaseException as err:
            return None


class partThread(threading.Thread):
    """分块上传"""

    def __init__(self, token, uid, idx, data):
        threading.Thread.__init__(self)
        self.is_Run = True
        self.token = token
        self.uid = uid
        self.idx = idx
        self.data = data

    def run(self):
        url = f"http://up-cn-east-2.qiniup.com/buckets/3vppt/objects/~/uploads/{self.uid}/{self.idx}"
        headers = {
            "Host": "up-cn-east-2.qiniup.com",
            "Content-Type": "application/octet-stream",
            "Authorization": f"UpToken {self.token}",
            "Content-Length": str(len(self.data)),
        }
        errcode = 0
        while True:
            try:
                print("分片上传", self.idx)
                res = requests.put(url, headers=headers, data=self.data, verify=False)
                r = res.json()
            except BaseException as err:
                errcode += 1
                print("分片错误", self.idx, err)
            else:
                print(f"分片完成 {self.idx}")
                r["partNumber"] = self.idx
                parts.append(r)
                break
            if errcode > 3:
                finish.append(self.idx)
                break
            time.sleep(2)
